package top.yoohome.verify.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import top.yoohome.verify.bean.*;

/**
 * Jwt相关工具类
 *
 * @author Johnny Zhang
 */
 public class JwtUtil {
    /** 秘钥 */
    private static final String JWT_SECRET = "verify##utools%#*!@#&~jwt#secret";
    /** 创建默认jwt，模式 */
    private static final int JWT_MODE_DEFAULT = 0;
    /** 创建自定义jwt，模式 */
    private static final int JWT_MODE_CUSTOM = 1;

    /**
     * 创建 JWT</br>
     *
     * iss(Issuser)：代表这个JWT的签发主体；</br>
     * sub(Subject)：代表这个JWT的主体，即它的所有人，这个是一个json格式的字符串，可以存放什么userid，roldid之类的，作为用户的唯一标志；</br>
     * aud(Audience)：代表这个JWT的接收对象；</br>
     * exp(Expiration time)：时间戳，代表这个JWT的过期时间，单位毫秒；</br>
     * nbf(Not Before)：时间戳，代表这个JWT生效的开始时间，意味着在这个时间之前验证JWT是会失败的，单位毫秒；</br>
     * iat(Issued at)：时间戳，代表这个JWT的签发时间，单位毫秒；</br>
     * jti(JWT ID)：是JWT的唯一标识。
     *
     * @param jwtObject jwt构建对象
     * @param mode 模式
     * @return jwt 加密的字符串
     */
    public static String createJwtToken(JwtObject jwtObject, int mode) {
        String token = "";
        switch (mode) {
            case JWT_MODE_DEFAULT:
                token = createJwtDefault(jwtObject);
                break;
            case JWT_MODE_CUSTOM:
                token = createJwtCustom(jwtObject);
                break;
            default:
                break;
        }
        return token;
    }

    /**
     * 创建默认 jwt token
     *
     * @param jwtObject jwt 构建对象
     * @return token
     */
    private static String createJwtDefault(JwtObject jwtObject) {
        return Jwts.builder()
                .setClaims(jwtObject.getClaims())
                .setClaims(jwtObject.getMap())
                .signWith(SignatureAlgorithm.HS256, JWT_SECRET)
                .compact();
    }

    /**
     * 创建自定义 jwt token
     *
     * @param jwtObject jwt构建对象
     * @return token
     */
    private static String createJwtCustom(JwtObject jwtObject) {
        return Jwts.builder()
                .setClaims(jwtObject.getClaims())
                .setClaims(jwtObject.getMap())
                .signWith(SignatureAlgorithm.HS256, JWT_SECRET)
                .compact();
    }

    /**
     * 校验 JWT
     *
     * @param token 需校验的 token
     * @return boolean 是否校验成功
     */
    public static Claims validateToken(String token) {
        try {
            return Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJws(token).getBody();
        } catch (Exception e){
            return null;
        }
    }
}
